package gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;

import misc.AutoComplete;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;

import database.DB_connection;
/*************************************************************
 * 
 * 
 * @author Brian Renzenbrink
 * @author Evan Nelson
 *
 *************************************************************/
public class Content_GraphingPane extends JPanel {
	
	private static final long serialVersionUID = 3149825197719836766L;
	private int currentCol = 0;
	private Dimension size;
	
	private XYDataset dataset;
	private JFreeChart chart;
    private ChartPanel chartPanel;

    private JComboBox chartTypeCB;
    private JComboBox exerciseCB;
    private JComboBox dateCB;

    private JButton buildGraphButton;
    private JButton addExerciseButton;

	private DB_connection conn;

	private ArrayList<String> DB_exercises = new ArrayList<String>();
	private ArrayList<String> DB_graphs = new ArrayList<String>();
	private ArrayList<String> cur_exercises = new ArrayList<String>();

	/*****************************************************************
	 * A constructor 
	 *****************************************************************/
	public Content_GraphingPane(Dimension size) {
		this.size = size;
		
		conn = new DB_connection();
		setExercises();
		setGraphs();
		
		initialize();
	}

	/*****************************************************************
	 * An initialization method for the chart
	 *****************************************************************/
	public void initialize(){
		setSize(this.size);
		setLayout(new GridBagLayout());

		GridBagConstraints c = new GridBagConstraints();
		
		//ROW ONE -- GRAPH
		buildGraph(DB_graphs.get(0));
                
        //ROW TWO -- OPTIONS (COMBO BOXES, ETC)
		c.insets = new Insets(0, 1, 1, 0);
        
        //labels
		c.anchor = GridBagConstraints.EAST;
		
        JLabel chartTypeLbl = new JLabel("Graph type: ");
        c.weightx = 0.1;
		c.gridx = 0;
		c.gridy = 1;
        add(chartTypeLbl, c);
		
        JLabel exerciseLbl = new JLabel("Exercise 1: ");
        c.weightx = 0.1;
		c.gridx = 2;
		c.gridy = 1;
        add(exerciseLbl, c);
        
        //comboboxes
        c.anchor = GridBagConstraints.WEST;
        
        chartTypeCB = new JComboBox();
        chartTypeCB.addItem("Lifts over time");
        chartTypeCB.setEditable(false);
        chartTypeCB.setPreferredSize(new Dimension(150, 25));
        chartTypeCB.setSelectedIndex(0);
        c.weightx = 0.1;
		c.gridx = 1;
		c.gridy = 1;
        add(chartTypeCB, c);
        
        exerciseCB = new AutoComplete(DB_exercises.toArray());
        exerciseCB.setPreferredSize(new Dimension(150, 25));
        exerciseCB.setSelectedIndex(0);
        c.weightx = 0.1;
		c.gridx = 3;
		c.gridy = 1;
        add(exerciseCB, c);
        
        buildGraphButton = new JButton("Build Graph");
        buildGraphButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				buildGraphButtonActionPerformed(evt);
			}
		});
		c.anchor = GridBagConstraints.CENTER;
        c.weightx = 0.5;
        c.gridx = 1;
        c.gridy = 2;
        add(buildGraphButton, c);
        
        addExerciseButton = new JButton("Add Exercise");
        addExerciseButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				addExerciseButtonActionPerformed(evt);
			}
		});
		c.anchor = GridBagConstraints.CENTER;
        c.weightx = 0.5;
        c.gridx = 3;
        c.gridy = 2;
        add(addExerciseButton, c);
        
        setVisible(true);
        updateUI();
	}
	
	private void buildGraphButtonActionPerformed(java.awt.event.ActionEvent e) {
		cur_exercises.clear();
		addExercise(exerciseCB.getSelectedItem().toString());
		buildGraph(chartTypeCB.getSelectedItem().toString());
	}
	
	private void addExerciseButtonActionPerformed(java.awt.event.ActionEvent e) {
		addExercise(exerciseCB.getSelectedItem().toString());
		buildGraph(chartTypeCB.getSelectedItem().toString());
	}
	
	private void buildGraph(String graphName) {
		if(chartPanel != null) {
			remove(chartPanel);
		}
		
		GridBagConstraints c = new GridBagConstraints();
		c.anchor = GridBagConstraints.NORTH;
        c.gridwidth = GridBagConstraints.REMAINDER;
        c.weightx = 1.0;
		c.insets = new Insets(1, 0, 10, 0);
		c.gridx = 0;
		c.gridy = 0;
        
		dataset = createDataset();
        chart = createChart(dataset);
        chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new Dimension(500, 340));
		
        System.out.println("Creating new graph");
        
        add(chartPanel, c);
        updateUI();
	}

	private void setGraphs() {
		DB_graphs.add("Lifts over time");
	}
	
	private void addExercise(String newExercise) {
		if(!cur_exercises.contains(newExercise)) {
			cur_exercises.add(newExercise);
		}
	}
	
	private void setExercises() {
		//Use conn to query the database for all exercises
		ResultSet rs;
		rs = conn.executeCurrentStatement("SELECT DISTINCT Exercise FROM Weightlifting ORDER BY Exercise");
		System.out.println("Display all exercises:");
		try{
			while(rs.next()){
				String str = rs.getString("Exercise");
				System.out.println(str);
				DB_exercises.add(str);
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private XYSeries createXYSeries(String title){
		XYSeries xys = new XYSeries(title);
		return xys;
	}
	
	private XYDataset createDataset() {
		
		if(cur_exercises.isEmpty()) {
			cur_exercises.add(DB_exercises.get(0));
		}

		final TimeSeriesCollection dataset = new TimeSeriesCollection();
        dataset.setDomainIsPointsInTime(true);
        

    	ResultSet rs;
        for(String exercise : cur_exercises) {
        	Random r = new Random();
        	final TimeSeries series = new TimeSeries(exercise, Day.class);
        	
    		rs = conn.executeCurrentStatement("SELECT max(weight), dateRecorded FROM Weightlifting " +
    				 "WHERE exercise = '" + exercise + "' GROUP BY exercise, dateRecorded");
    		System.out.println("Adding time series for " + exercise);
    		try{
    			while(rs.next()){
    				int weight = rs.getInt("max(weight)");
    				Date dateRecorded = rs.getDate("dateRecorded");
    				System.out.println("Adding (weight, date): (" + weight + ", " + dateRecorded + ")");
    	        	series.add(new Day(dateRecorded), weight);
    			}
                dataset.addSeries(series);
    		}
    		catch (Exception e) {
    			e.printStackTrace();
    		}
        }

        return dataset;

	}

	private JFreeChart createChart(final XYDataset dataset) {

		// create the chart...
		final JFreeChart chart = ChartFactory.createTimeSeriesChart(
				"Sample Chart",
	            "Date", 
	            "Max Weight",
	            dataset,
	            true,
	            true,
	            false
	        );

		//make background transparent
		chart.setBackgroundPaint(new Color(0, 0, 0, 0));

		// get a reference to the plot for further customisation...
		final XYPlot plot = chart.getXYPlot();
		plot.setBackgroundPaint(Color.lightGray);
		//    plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0));
		plot.setDomainGridlinePaint(Color.white);
		plot.setRangeGridlinePaint(Color.white);

		final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
		//renderer.setSeriesLinesVisible(0, false);
		renderer.setSeriesShapesVisible(1, true);
		renderer.setSeriesShapesVisible(2, true);
		renderer.setSeriesShapesVisible(3, true);
		plot.setRenderer(renderer);

		return chart;

	}
}
